# 步骤 1: 创建命令接口
class Command:
    """命令抽象类"""

    def execute(self):
        raise NotImplementedError("Subclasses must implement this method")

    def undo(self):
        raise NotImplementedError("Subclasses must implement this method")


# 步骤 2: 创建具体命令
class AddTextCommand(Command):
    """添加文本的命令"""

    def __init__(self, receiver, text):
        self.receiver = receiver
        self.text = text
        self.last_index = 0

    def execute(self):
        self.last_index = self.receiver.add_text(self.text)

    def undo(self):
        self.receiver.remove_text(self.last_index, len(self.text))


class RemoveTextCommand(Command):
    """删除文本的命令"""

    def __init__(self, receiver, start, length):
        self.receiver = receiver
        self.start = start
        self.length = length
        self.removed_text = ""

    def execute(self):
        self.removed_text = self.receiver.remove_text(self.start, self.length)

    def undo(self):
        self.receiver.add_text_at(self.removed_text, self.start)


# 步骤 3: 创建接收者
class TextEditor:
    """接收者：文本编辑器，实现添加和删除文本功能"""

    def __init__(self, text=""):
        self.text = text

    def add_text(self, text):
        self.text += text
        return len(self.text) - len(text)

    def remove_text(self, index, length):
        removed_text = self.text[index:index + length]
        self.text = self.text[:index] + self.text[index + length:]
        return removed_text

    def add_text_at(self, text, index):
        self.text = self.text[:index] + text + self.text[index:]


# 步骤 4: 创建调用者
class CommandInvoker:
    """请求者：执行命令"""

    def __init__(self):
        self.history = []

    def execute_command(self, command):
        command.execute()
        self.history.append(command)

    def undo_last(self):
        if self.history:
            command = self.history.pop()
            command.undo()


if __name__ == '__main__':
    editor = TextEditor()
    invoker = CommandInvoker()

    add_command = AddTextCommand(editor, "Hello, World!")
    invoker.execute_command(add_command)
    print(editor.text)  # Hello, World!

    remove_command = RemoveTextCommand(editor, 5, 7)
    invoker.execute_command(remove_command)
    print(editor.text)  # Hello!

    invoker.undo_last()
    print(editor.text)  # Hello, World!

    invoker.undo_last()
    print(editor.text)  # (空)

'''Hello, World!
Hello!
Hello, World!

'''